package org.hose.core;

import cn.hutool.core.exceptions.ExceptionUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.log.Log;
import cn.hutool.poi.excel.ExcelUtil;
import com.microsoft.playwright.BrowserContext;
import com.microsoft.playwright.Page;
import io.qameta.allure.Allure;

import java.io.ByteArrayInputStream;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

/**
 * UI 执行器，实现通过 TestCaseStep 执行 UI 操作
 */
public class UIExecutor {
    private static final Log log = Log.get(UIExecutor.class);

    public static void execute(TestCase testCase, Page page, BrowserContext context) {
        UICommandPlaywright command = new UICommandPlaywright(page, context);
        for (TestCaseStep step : testCase.getSteps()) {
            Method method = ReflectUtil.getMethodByName(UICommandPlaywright.class, step.getCommand());
            Assert.notNull(method, "未找到方法：" + step.getCommand());
            List<Object> args = new ArrayList<>();
            if (ObjUtil.isNotEmpty(step.getTargetElement())) {
                args.add(step.getTargetElement());
            }
            if (ObjUtil.isNotEmpty(step.getParameter())) {
                args.add(step.getParameter());
            }
            String stepDesc = StrUtil.concat(true,
                    step.getDescription(),
                    ", 动作: [ ", step.getCommand(),
                    " ], 元素: [ ", step.getTargetElement(),
                    " ], 数据: [ ", step.getParameter(), " ]");
            Allure.step(stepDesc, () -> {
                try {
                    if (ArrayUtil.isEmpty(args)) {
                        ReflectUtil.invoke(command, method);
                    } else {
                        ReflectUtil.invoke(command, method, args.toArray());
                    }
                } catch (Exception e) {
                    // 剥离反射的异常信息
                    Throwable unwrap = ExceptionUtil.unwrap(e);
                    String errorMessage = StrUtil.concat(false, "执行【当前步骤】异常: ", stepDesc, "\n 错误详情：\n", ExceptionUtil.stacktraceToString(unwrap, -1));
                    Allure.addAttachment(StrUtil.concat(false, "Error-",UUID.randomUUID().toString(), ".log"), errorMessage);
                    log.error(e, errorMessage);
                    //抛出异常
                    ExceptionUtil.wrapRuntimeAndThrow(StrUtil.concat(false,"执行【当前步骤】异常: ", stepDesc, ", 错误详情见ErrorLog"));
                } finally {
                    // 截图
                    byte[] bytes = page.screenshot();
                    Allure.addAttachment(StrUtil.concat(false, UUID.randomUUID().toString(), ".png"), new ByteArrayInputStream(bytes));
                }
            });
        }

    }

}
